﻿using China.Core;
using Fur;
using Fur.Authorization;
using Fur.Core;
using Fur.DatabaseAccessor;
using Fur.DynamicApiController;
using Fur.FriendlyException;
using Fur.LinqBuilder;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;

namespace China.Application
{
    [AppAuthorize]
    public class RBACServices : IDynamicApiController
    {
        private readonly IRepository<User> _userRepository;
        public RBACServices(IRepository<User> userRepository)
        {
            _userRepository = userRepository;
        }

        [AllowAnonymous]
        [IfException(1000, ErrorMessage = "用户名或密码错误")]
        public LoginOutput Login(LoginInput input)
        {
            var user = _userRepository.FirstOrDefault(u => u.Account.Equals(input.Account) && u.Password.Equals(input.Password))
                ?? throw Oops.Oh(1000);

            var output = user.Adapt<LoginOutput>();

            var jwtSettings = App.GetOptions<JWTSettingsOptions>();
            var datetimeOffset = new DateTimeOffset(DateTime.Now);
            output.Token = JWTEncryption.Encrypt(jwtSettings.IssuerSigningKey, new JObject()
            {
                 { "UserId", user.Id },  // 存储Id
                { "Account",user.Account }, // 存储用户名

                { JwtRegisteredClaimNames.Iat, datetimeOffset.ToUnixTimeSeconds() },
                { JwtRegisteredClaimNames.Nbf, datetimeOffset.ToUnixTimeSeconds() },
                { JwtRegisteredClaimNames.Exp, new DateTimeOffset(DateTime.Now.AddSeconds(jwtSettings.ExpiredTime.Value*60)).ToUnixTimeSeconds() },
                { JwtRegisteredClaimNames.Iss, jwtSettings.ValidIssuer},
                { JwtRegisteredClaimNames.Aud, jwtSettings.ValidAudience }
            });

            return output;
        }

        /// <summary>
        /// 查询用户拥有的所有角色
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        [SecurityDefine(SecurityConst.GET_USER_ROLE)]
        public List<RoleDto> GetUserRoles(int userId)
        {
            return _userRepository.Include(u => u.Roles)
                    .Where(u => u.Id == userId)
                    .SelectMany(u => u.Roles)
                    .ToList()
                    .Adapt<List<RoleDto>>();
        }

        /// <summary>
        /// 为用户分配角色
        /// </summary>
        /// <param name="userRoleRepository"></param>
        /// <param name="userId"></param>
        /// <param name="roleIds"></param>
        [SecurityDefine(SecurityConst.GIVEN_USER_ROLE)]
        public void GivenUserRoles([FromServices] IRepository<UserRole> userRoleRepository, [Required] int userId, int[] roleIds)
        {
            roleIds ??= Array.Empty<int>();

            // 删除
            userRoleRepository.Delete(
                userRoleRepository.Where(u => u.UserId == userId).AsEnumerable());

            var list = new List<UserRole>();
            foreach (var roleId in roleIds)
            {
                list.Add(new UserRole { UserId = userId, RoleId = roleId });
            }

            userRoleRepository.Insert(list);
        }

        [SecurityDefine(SecurityConst.GET_NAME)]
        public void GetName()
        {

        }
    }
}
